package com.changcheng.project.yuminsi.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @description: 生成签名
 * @author: elvin
 * @create: 2019-08-22 16:04
 **/
@SuppressWarnings("all")
public class GenerateSignUtil {

    private static final Logger logger = LoggerFactory.getLogger(GenerateSignUtil.class);

    private static String appkey = "9065275281";
    private static String secretkey = "2b673290caa2d9a82f1f7e845c80e4fe";


    /**
     * 1.请求方式+url+header+paratmer+secretkey
     * 2.进 行 urlencode 并计算 sha256 值
     * get请求
     *
     * @throws Exception
     */
    public static String generateSignOfGet(String url, String appkey, String nonce, String timestamp, Map<String, Object> parameters, String secretkey) throws Exception {


        ObjectMapper objectMapper = new ObjectMapper();

        // headers
        Map<String, String> headers = new HashMap<>();
        headers.put("bt-auth-appkey", appkey);
        headers.put("bt-auth-nonce", nonce);
        headers.put("bt-auth-timestamp", timestamp);
        TreeMap<String, String> sortHeaderMap = new TreeMap<>(Comparator.comparing(String::toLowerCase));
        sortHeaderMap.putAll(headers);

        // GET parameter
//        Map<String, Object> parameters = new HashMap<>();
//        parameters.put("fenceId", "1");
//        parameters.put("gence", "");

        TreeMap<String, Object> sortParameterMap = new TreeMap<>(Comparator.comparing(String::toLowerCase));
        sortParameterMap.putAll(parameters);

        StringBuilder signStr = new StringBuilder();

        // append  method & url
        signStr.append("GET").append(url);

        // append headers
        for (Map.Entry<String, String> header : sortHeaderMap.entrySet()) {
            signStr.append(header.getKey().toLowerCase()).append(":").append(header.getValue());
        }


        // append GET parameters
//        for (Map.Entry<String, Object> parameter : sortParameterMap.entrySet()) {
//            signStr.append(parameter.getKey().toLowerCase()).append("=").append(parameter.getValue());
//        }

        for (Map.Entry<String, Object> parameter: sortParameterMap.entrySet()) {
            //如果参数的key不为null，走里面的
            if (!StringUtils.isEmpty(parameter.getKey())){
                signStr.append(parameter.getKey().toLowerCase()).append("=").append(parameter.getValue());
            }
        }

        // append secretkey
        signStr.append(secretkey);
        logger.info("拼接完成的字符串： {}",signStr);
        byte[] bytes = (URLEncoder.encode(signStr.toString(), "UTF-8")).getBytes("UTF-8");

        String sign = sha256Digest(bytes);
        return sign;

        // print
//        System.out.println("headers is: " + objectMapper.writeValueAsString(sortHeaderMap));
//        System.out.println("sortParameterMap is: " + objectMapper.writeValueAsString(sortParameterMap));
//        System.out.println("sign before sha256 is: " +signStr.toString());
//        System.out.println("timestamp is: " + timestamp);
//        System.out.println("sign is: " + sign);

    }


    /**
     * 1.请求方式+url+header+body+secretkey
     * 2.进 行 urlencode 并计算 sha256 值
     * post请求
     *
     * @throws Exception
     */
    public static String generateSignOfPost(String url, String appkey, String nonce, String timestamp, Map<String, Object> postBody, String secretkey) throws Exception {

        ObjectMapper objectMapper = new ObjectMapper();

        // headers
        Map<String, String> headers = new HashMap<>();
        headers.put("bt-auth-appkey", appkey);
        headers.put("bt-auth-nonce", nonce);
        headers.put("bt-auth-timestamp", timestamp);

        TreeMap<String, String> sortHeaderMap = new TreeMap<>(Comparator.comparing(String::toLowerCase));
        sortHeaderMap.putAll(headers);

        // POST param & body
//        Map<String, Object> postBody = new HashMap<>();
//        postBody.put("json", "{\"accountName\":\"15330228758\",\"password\":\"8d7ba5939bc2a3ecdc86c22477dc88db\"}".replaceAll("\\s", "").replaceAll("\n", ""));
        TreeMap<String, Object> sortPostBody = new TreeMap<>(Comparator.comparing(String::toLowerCase));
        sortPostBody.putAll(postBody);

        StringBuilder signStr = new StringBuilder();

        // append  method & url
        signStr.append("POST").append(url);

        // append headers
        for (Map.Entry<String, String> header : sortHeaderMap.entrySet()) {
            signStr.append(header.getKey().toLowerCase()).append(":").append(header.getValue());
        }

        // append POST parameters
        for (Map.Entry<String, Object> parameter : sortPostBody.entrySet()) {
            signStr.append(parameter.getKey().toLowerCase()).append("=").append(parameter.getValue());
        }

        // append secretkey
        signStr.append(secretkey);
        logger.info("拼接完成的字符串： {}",signStr);
//        byte[] bytes = (URLEncoder.encode(signStr.toString(), "UTF-8")).getBytes("UTF-8");
        byte[] bytes = (URLEncoder.encode(signStr.toString().replace(" ",""), "UTF-8")).getBytes("UTF-8");

        String sign = sha256Digest(bytes);
        return sign;

    }

    private static String sha256Digest(byte[] content) throws Exception {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return toHexString(md.digest(content));
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    private static String toHexString(byte[] digestBytes) {
        StringBuilder hexStr = new StringBuilder();
        for (byte b : digestBytes) {
            hexStr.append(String.format("%02x", b & 0xff));
        }
        return hexStr.toString();
    }


}
